# coding=utf-8
"""guiclasses.py,
classes for PrimerPy graphic interface

update status:
    InputPage.GetValues() has gui_input_dict ready for InputDict
    relaying ...


"""

import wx
import wx.html
from Primer3Wrapper import *

from GlobalConf import *
#get global parameters and run records
GC = GlobalConf()
record = GC.get_record()
#run_num, last_run_result
RUN_NUM = record['run_num']
LAST_RUN_RESULT = record['last_run_result']
#path & files
global_config = GC.readconf()
Primer3_PATH = global_config['Primer3_exe_Path']
UserDataDir = global_config['UserDataDir']
LogFile = os.path.join(UserDataDir, global_config['LogFile'])



class TemplatePanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        vbox = wx.BoxSizer(wx.VERTICAL)
        text1 = wx.StaticText(self, label='Paste your template sequence here:')
        vbox.Add(text1)
        self.template = wx.TextCtrl(self, size=(270,90), style=wx.TE_MULTILINE)
        self.template.SetInsertionPoint(0)
        vbox.Add(self.template)
        hbox1 = wx.BoxSizer(wx.HORIZONTAL)
        self.paste_button = wx.Button(self, 11, 'Paste')
        self.Bind(wx.EVT_BUTTON, self.paste, self.paste_button)
        hbox1.Add(self.paste_button)
        self.clear_button = wx.Button(self, 12, 'Clear All')
        self.Bind(wx.EVT_BUTTON, self.clear_all, self.clear_button)
        hbox1.Add(self.clear_button)
        hbox1.Add((15,-1))
        self.design_button = wx.Button(self, 13, 'Design')
        self.Bind(wx.EVT_BUTTON, self.design, self.design_button)
        hbox1.Add(self.design_button)
        vbox.Add(hbox1)
        self.SetSizer(vbox)
        
    def ProcessTemplate(self, text):
        #process input template, return PRIMER_SEQUENCE_ID, SEQUENCE
        global run_time, RUN_NUM
        text=text.replace(" ", "")
        if text == "":
            self.GetParent().GetParent().GetParent().statusbar.SetStatusText("No Template!")
        elif text[0]==">":
            firstline=max(text.find('\n'), text.find('\r'))
            t = text[firstline+1: ].replace("\n", "").replace("\r", "")
            return text[ :firstline], t
        else:
            return run_time+'_run'+str(RUN_NUM), text.replace("\n", "").replace("\r", "")
    def get(self):
        a = self.ProcessTemplate(self.template.GetValue())
        return {'PRIMER_SEQUENCE_ID' : a[0], 'SEQUENCE' : a[1]}
    def paste(self, event):
        self.template.Paste()
    def clear_all(self, event):
        self.template.Clear()
        self.GetParent().clear2()
    def design(self, event):
        self.GetParent().design()

class OptionPanel(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        sizer = wx.GridSizer(rows=4, cols=2)
        sizer.Add(wx.StaticText(self, label="Predefine left primer:"))
        sizer.Add(wx.StaticText(self, label="Users' Note:"))
        self.LeftPrimer = wx.TextCtrl(self, size=(160,-1))
        sizer.Add(self.LeftPrimer)
        self.UserNote = wx.TextCtrl(self, size=(160,-1))
        sizer.Add(self.UserNote)
        sizer.Add(wx.StaticText(self, label="Predefine right primer:"))
        sizer.Add(wx.StaticText(self, label="Desired Amplicon size:"))
        self.RightPrimer = wx.TextCtrl(self, size=(160,-1))
        sizer.Add(self.RightPrimer)
        hbox = wx.BoxSizer(wx.HORIZONTAL)
        self.AmpliconSize = wx.TextCtrl(self)
        hbox.Add(self.AmpliconSize)
        hbox.Add(wx.StaticText(self, label="(80~300)"))
        sizer.Add(hbox)
        self.SetSizer(sizer)
        self.Show(False)
    def get(self):
        #return a dictionary of paramters
        options_dict={
            'PRIMER_LEFT_INPUT' : self.LeftPrimer.GetValue().replace(" ", ""),
            'PRIMER_RIGHT_INPUT' : self.RightPrimer.GetValue().replace(" ", ""),
            'PRIMER_PRODUCT_OPT_SIZE' : self.AmpliconSize.GetValue().replace(" ", ""),
            'Users_Note' : self.UserNote.GetValue()
            }
        return options_dict
    def clear3(self):
        self.LeftPrimer.Clear()
        self.RightPrimer.Clear()
        self.UserNote.Clear()
        self.AmpliconSize.Clear()


class InputPage(wx.Panel):
    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        icon = wx.StaticBitmap(self, -1, wx.Bitmap('eleboa.jpg'), pos=(30,60), size=(120,80))
        #-------------Template Panel
        self.tp = TemplatePanel(self)
        self.tp.SetPosition((180, 30))
        self.tp.SetSize((300, 150))
        #-------------
        self.more_button = wx.ToggleButton(self, -1, 'More Options >>>', pos=(180,180))
        #-------------Option Panel
        self.mo = OptionPanel(self)
        self.mo.SetPosition((160, 220))
        self.mo.SetSize((360, 88))
        self.Bind(wx.EVT_TOGGLEBUTTON, self.ShowOptions, self.more_button)
        
        self.Center()
        self.Show()

    def ShowOptions(self, event):
        self.mo.Show(self.more_button.GetValue())
    def clear2(self):
        # continued from self.tp.clear_all
        if self.more_button.GetValue():
            self.mo.clear3()
    def GetValues(self):
        gui_input_dict = self.tp.get()
        if self.more_button.GetValue():
            x = self.mo.get()
            for key,value in x:
                if value != '':
                    gui_input_dict[key] = value
        return gui_input_dict

    def design(self):
        global GC, RUN_NUM, UserDataDir, Primer3_PATH, LAST_RUN_RESULT, run_time
        RUN_NUM += 1
        LAST_RUN_RESULT = run_time + 'run' + str(RUN_NUM) + '.txt'
        LAST_RUN_RESULT = os.path.join(UserDataDir, LAST_RUN_RESULT)
        gui_input_dict = self.GetValues()
        input_dict = InputDict(gui_input_dict).input_dict
        run = ThinWrapper()
        run_result = run.design_logic_loop(Primer3_PATH, input_dict, RUN_NUM)
        self.write_result_log(run_result, LAST_RUN_RESULT)
        record = {'run_num' : RUN_NUM, 'last_run_result' : LAST_RUN_RESULT}
        GC.flush_record(record)
        self.GetParent().show_result()

    def write_result_log(self, run_result, LAST_RUN_RESULT):
        global LogFile
        out = open(LAST_RUN_RESULT, 'w')
        out.write(run_result.result)
        out.close()
        out = open(LogFile, 'a')
        out.write(run_result.log)
        out.write('result saved as: ' +LAST_RUN_RESULT+ '\n')
        out.close()

class PrimerNoteBook(wx.Notebook):
    def __init__(self, parent):
        wx.Notebook.__init__(self, parent, style=wx.NB_TOP)
        
        self.sheet_design = InputPage(self)
        self.sheet_manual = wx.html.HtmlWindow(self)
        
        self.AddPage(self.sheet_design, "design")
        self.AddPage(self.sheet_manual, "manual")
        self.sheet_manual.LoadFile('primerpy_tutorial.htm')
        self.sheet_design.SetFocus()
        
    def show_result(self):
        global LAST_RUN_RESULT
        #if not self.sheet_result.IsShown():
        self.sheet_result = wx.html.HtmlWindow(self)
        self.AddPage(self.sheet_result, "result")
        self.sheet_result.LoadFile(LAST_RUN_RESULT)
    def show_log(self):
        global LogFile
        self.sheet_log = wx.html.HtmlWindow(self)
        self.AddPage(self.sheet_log, "log")
        self.sheet_log.LoadFile(LogFile)
        #self.sheet_log.Show()

class configure_dialog(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, "Configure PrimerPy")
    def donothing(self):
        pass

#class about_boa, AboutDialog

class AboutPrimerPy(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, "About PrimerPy", size=(300, 300) )
        icon = wx.StaticBitmap(self, -1, wx.Bitmap('eleboa.jpg') )
        info = wx.StaticText(self, -1,
            "PrimerPy is a primer design tool\n"
            "optimized for SyBr Green QPCR, \nfree under GNU/GPL.\n"
            "Copyright 2007, Shuzhao Li\n"
            "http://www.bioinformatics.org/primerpy\n\n"
            "This version of PrimerPy uses Primer3 (primer3.sourceforge.net) as backend engine.\n", 
            style=wx.ALIGN_CENTER
            )
        button = wx.Button(self, wx.ID_OK, "Close")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((-1, 5))
        sizer.Add(icon, 0, wx.ALIGN_CENTER)
        sizer.Add((-1, 15))
        sizer.Add(info, 0, wx.EXPAND|wx.ALL)
        sizer.Add(button, 0, wx.ALIGN_CENTER)
        self.SetSizer(sizer)

class AboutBoa(wx.Dialog):
    def __init__(self, parent):
        wx.Dialog.__init__(self, parent, -1, "About the Boa", size=(280, 240) )
        title = wx.StaticText(self, -1, "Elephant in a snake")
        pic = wx.StaticBitmap(self, -1, wx.Bitmap('boa0.jpg'), size=(100, 66) )
        caption = wx.StaticText(self, -1, "from The Little Prince\n"
            "by Antoine de Saint Exupéry\n")
        button = wx.Button(self, wx.ID_OK, "Close")
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add((-1, 15))
        sizer.Add(title, 0, wx.ALIGN_CENTER)
        sizer.Add((-1, 15))
        sizer.Add(pic, 0, wx.ALIGN_CENTER)
        sizer.Add((-1, 15))
        sizer.Add(caption, 0, wx.ALIGN_CENTER)
        sizer.Add(button, 0, wx.ALIGN_CENTER)
        self.SetSizer(sizer)





